package com.faxsun.core.order.service.worklow;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.broadleafcommerce.core.catalog.domain.Category;
import org.broadleafcommerce.core.catalog.domain.Product;
import org.broadleafcommerce.core.catalog.service.CatalogService;
import org.broadleafcommerce.core.order.domain.DiscreteOrderItem;
import org.broadleafcommerce.core.order.domain.OrderItem;
import org.broadleafcommerce.core.order.service.OrderItemService;
import org.broadleafcommerce.core.order.service.call.OrderItemRequestDTO;
import org.broadleafcommerce.core.order.service.workflow.CartOperationRequest;
import org.broadleafcommerce.core.workflow.BaseActivity;
import org.broadleafcommerce.core.workflow.ProcessContext;
import org.broadleafcommerce.profile.core.domain.Customer;

import com.faxsun.core.catalog.service.CategoryConstants;
import com.faxsun.core.order.service.FSOrderItemServiceImpl;
import com.faxsun.core.order.service.exception.TreasureDisqualifiedException;
import com.faxsun.profile.core.domain.FSCustomer;

public class VerifyTreasureQualifiedActivity extends BaseActivity<ProcessContext<CartOperationRequest>> {

    @Resource(name = "blCatalogService")
    protected CatalogService catalogService;

    @Resource(name = "blOrderItemService")
    protected OrderItemService orderItemService;

    private static final int MAX_HIT = 3;
    private static final String ONE_PIECE_MESSAGE = "一种奖品只能夺一次。奖品这么丰富，换一个吧！";
    private static final String EXCEED_MAX_MESSAGE = "您已经夺了三次宝了，把机会留给别人吧！";
    private static final String LOGIN_MESSAGE = "正在为您转到登录页面...";
    private static final String VERIFY_MOBILE_MESSAGE = "为保证中奖后能及时联系您，请前往账户信息页填写手机号码";

    @Override
    public ProcessContext<CartOperationRequest> execute(ProcessContext<CartOperationRequest> context)
        throws Exception {
        CartOperationRequest request = context.getSeedData();

        Customer customer = request.getOrder().getCustomer();
        // Not allow to treasure anonymously
        if (customer.isAnonymous()) {
            throw new TreasureDisqualifiedException(LOGIN_MESSAGE);
        }

        if (customer instanceof FSCustomer) {
            FSCustomer fsCustomer = (FSCustomer) customer;
            if (!fsCustomer.isVerified()) {
                throw new TreasureDisqualifiedException(VERIFY_MOBILE_MESSAGE);
            }
        }

        OrderItemRequestDTO orderItemRequestDTO = request.getItemRequest();
        // Not allow to treasure 2 pieces at one time
        if (orderItemRequestDTO.getQuantity() > 1) {
            throw new TreasureDisqualifiedException(ONE_PIECE_MESSAGE);
        }

        Product product = catalogService.findProductById(orderItemRequestDTO.getProductId());
        Category category = product.getDefaultCategory();

        FSOrderItemServiceImpl fsOrderItemService = (FSOrderItemServiceImpl) orderItemService;
        List<OrderItem> orderItemsOfTreasure = fsOrderItemService.findOrderItemsByCustomerAndCategory(
            customer, category);
        Map<String, List<Product>> orderItemsMap = new HashMap<String, List<Product>>();
        SimpleDateFormat yearWW = new SimpleDateFormat("yyyyww");

        if (orderItemsOfTreasure != null) {
            // Not allow to treasure more than one time for a specific Sku
            for (OrderItem orderItem : orderItemsOfTreasure) {
                if (orderItem instanceof DiscreteOrderItem) {
                    DiscreteOrderItem discreteOrderItem = (DiscreteOrderItem) orderItem;
                    if (discreteOrderItem.getSku().getId().equals(orderItemRequestDTO.getSkuId())) {
                        throw new TreasureDisqualifiedException(ONE_PIECE_MESSAGE);
                    }

                    Product productOrdered = ((DiscreteOrderItem) orderItem).getProduct();
                    String date = yearWW.format(productOrdered.getActiveStartDate());
                    if (!orderItemsMap.containsKey(date)) {
                        orderItemsMap.put(date, new ArrayList<Product>());
                    }
                    orderItemsMap.get(date).add(productOrdered);
                }
            }

            // if (orderItemsOfTreasure.size() >= MAX_HIT) {
            String productStartDate = yearWW.format(product.getActiveStartDate());
            if (orderItemsMap.containsKey(productStartDate)
                && orderItemsMap.get(productStartDate).size() >= MAX_HIT) {
                throw new TreasureDisqualifiedException(EXCEED_MAX_MESSAGE);
            }
        }

        return context;
    }

    @Override
    public boolean shouldExecute(ProcessContext<CartOperationRequest> context) {
        // return false;

        CartOperationRequest request = context.getSeedData();
        OrderItemRequestDTO orderItemRequestDTO = request.getItemRequest();

        Product product = null;
        if (orderItemRequestDTO.getProductId() != null) {
            product = catalogService.findProductById(orderItemRequestDTO.getProductId());
        }

        Category category = null;
        if (product != null) {
            category = product.getDefaultCategory();
        }

        if (category != null && category.getName().equals(CategoryConstants.TREASURE)) {
            return true;
        } else {
            return false;
        }

    }
}
